#ifndef DOUBLEBF_HPP
#define DOUBLEBF_HPP

#include <mutex>
#include <deque>
#include <thread>

template<typename T>
class DoubleBf
{
protected:
    std::deque<T*> bf;
    std::mutex lock;

public:
    DoubleBf()
    {

    }

    virtual ~DoubleBf()
    {
        Release();
    }

    void Write(T* &w0)
    {
        lock.lock();
        bf.push_back(w0);
        lock.unlock();
    }

    bool TryRead(T* &r0)
    {
        lock.lock();
//        std::cout<<"bf="<<bf.size()<<"\n"<<std::flush;
        if(!bf.empty())
        {
            r0=bf[0];
            bf.pop_front();
            lock.unlock();
            return true;
        }
        lock.unlock();
        return false;
    }

    void Read(T* &r0)
    {
        while(!TryRead(r0))
        {
            std::this_thread::yield();
        }
    }

    void Release()
    {
        lock.lock();
        while(!bf.empty())
        {
            delete bf.front();
            bf.pop_front();
        }
        lock.unlock();
    }

};


#endif // DOUBLEBF_HPP

